﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Bukstor.Biz;

namespace Bukstor.UI.Miembros
{
    public partial class CompraPago : System.Web.UI.Page
    {
        BukstorBDEntities entidades;

        protected void Page_Load(object sender, EventArgs e)
        {
            entidades = new BukstorBDEntities();
        }

        protected void btnTarjetaPagar_Click(object sender, EventArgs e)
        {
            int idCliente = (int)Session["cliente"];
            Cliente cliente = entidades.Clientes.First(i => i.id == idCliente);
            int idDireccion = (int)Session["direccion"];
            Direccion direccion = entidades.Direcciones.First(i => i.id == idDireccion);
            if (!direccion.ProvinciaReference.IsLoaded) direccion.ProvinciaReference.Load();
            if (!direccion.Provincia.CostoReference.IsLoaded) direccion.Provincia.CostoReference.Load();
            decimal total = (decimal)Session["total"];
            Carrito carrito = Session["carrito"] as Carrito;
            
            Pedido P = Pedido.CreatePedido(0, (double)total, DateTime.Now);
            P.Cliente = cliente;
            P.Direccion = direccion;
            P.entregaEstimada = DateTime.Today.AddDays(direccion.Provincia.Costo.plazo);
            P.Estado = entidades.EstadosDeLosPedidos.First(i => i.idEstado == 1);
            entidades.SaveChanges();
            entidades.Refresh(System.Data.Objects.RefreshMode.StoreWins, P);

            foreach (KeyValuePair<int,int> art in carrito.Compra)
            {
                Linea L = Linea.CreateLinea(P.id, art.Key, art.Value);
                L.Libro = entidades.Libros.First(i => i.id == art.Key);
                if (!L.Libro.InventarioReference.IsLoaded) L.Libro.InventarioReference.Load();
                reducirInventario(L.Libro, art.Value);
                P.LineasDelPedido.Add(L);
            }
            entidades.SaveChanges();
            carrito.Vaciar();
            Session["reservas"] = new List<int>();
            Response.Redirect("CompraGracias.aspx", true);
        }

        /// <summary>
        /// Disminuye el inventario y elimina las reservas asociadas
        /// </summary>
        /// <param name="L">Libro que se está comprando</param>
        /// <param name="cantidad">Cantidad que se está comprando</param>
        /// <remarks>
        /// El proceso es complicado si hay reserva
        /// La reserva toma stock como una venta, por lo que no debe deducirse el stock reservado que finalmente de vende
        /// Pero si esa reserva o parte de ella no se vende, debe sumarse al stock también
        /// </remarks>
        private void reducirInventario(Libro L, int cantidad)
        {
            int inventarioReservado = 0;
            List<Reserva> reservasDeEsteLibro = new List<Reserva>();
            if (!L.InventarioReference.IsLoaded) L.InventarioReference.Load();
            foreach (int idReserva in (Session["reservas"] as List<int>))
            {
                Reserva reserva = entidades.Reservas.First(i => i.id == idReserva);
                if (reserva.Libro.id == L.id)
                {
                    inventarioReservado += reserva.cantidad;
                    reservasDeEsteLibro.Add(reserva);
                }
            }
            if (cantidad > inventarioReservado)
            {
                L.Inventario.cantidad -= (cantidad - inventarioReservado);
            }
            else
            {
                L.Inventario.cantidad += (inventarioReservado - cantidad);
            }
            foreach (Reserva R in reservasDeEsteLibro)
            {
                entidades.DeleteObject(R);
            }
        }

        /// <summary>
        /// Devuelve el detalle de la compra, incluído el costo de envío correspondiente.
        /// También carga en la variable de sesión 'total' el correspondiente valor
        /// </summary>
        /// <returns>Una colección de objetos para mostrar el detalle a facturar</returns>
        public IEnumerable<CompraPagoRow> cargarDetalle()
        {
            BukstorBDEntities entities=new BukstorBDEntities();
            Carrito C = Session["carrito"] as Carrito;
            int idDireccion = (int)Session["direccion"];
            Direccion D = entities.Direcciones.First(i => i.id == idDireccion);
            
            List<CompraPagoRow> salida = new List<CompraPagoRow>();
            int cantidadDeArticulos = 0;
            decimal totalDeLaCompra = 0;

            foreach (KeyValuePair<int,int> art in C.Compra)
            {
                Libro L = entities.Libros.First(i => i.id == art.Key);
                if(!L.InventarioReference.IsLoaded)L.InventarioReference.Load();
                CompraPagoRow fila = new CompraPagoRow();
                fila.Articulo = L.titulo;
                fila.Cantidad = art.Value;
                fila.PrecioUnitario = L.Inventario.precioUnitario;
                salida.Add(fila);
                cantidadDeArticulos += art.Value;
                totalDeLaCompra += fila.SubTotal;
            }
            CompraPagoRow costoDeEnvio = new CompraPagoRow();
            costoDeEnvio.Articulo = "Costo de envío";
            costoDeEnvio.Cantidad = 1;
            if (totalDeLaCompra>300)
            {
                costoDeEnvio.Articulo += " (Bonificado)";
                costoDeEnvio.PrecioUnitario = 0;
            }
            else
            {
                if(!D.ProvinciaReference.IsLoaded)D.ProvinciaReference.Load();
                if(!D.Provincia.CostoReference.IsLoaded)D.Provincia.CostoReference.Load();
                CostoPorProvincia CPP = D.Provincia.Costo;
                costoDeEnvio.PrecioUnitario += CPP.costoPorPedido;
                costoDeEnvio.PrecioUnitario += cantidadDeArticulos * CPP.costoPorArticulo;
            }
            salida.Add(costoDeEnvio);
            Session["total"] = totalDeLaCompra + costoDeEnvio.SubTotal;
            return salida;
        }

        protected void gvDetallePedido_DataBound(object sender, EventArgs e)
        {
            gvDetallePedido.FooterRow.Cells[0].Text = "TOTAL";
            gvDetallePedido.FooterRow.Cells[3].Text = Session["total"].ToString();
        }
    }
}
